package be.nvlooy.moviereminder.service.implementations;

import java.awt.image.BufferedImage;
import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;

import javax.imageio.ImageIO;

import org.json.JSONException;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Service;

import be.nvlooy.moviereminder.dto.MovieDTO;
import be.nvlooy.moviereminder.entities.OriginalSourceType;
import be.nvlooy.moviereminder.service.BasicService;
import be.nvlooy.moviereminder.service.MovieSourceService;

import net.sf.jtmdb.GeneralSettings;
import net.sf.jtmdb.MovieImages;
import net.sf.jtmdb.MoviePoster;

@Service("tmdbService")
@Scope("singleton")
public class TmdbServiceImpl extends BasicService implements MovieSourceService {
	
	TmdbServiceImpl() {
		GeneralSettings.setApiKey("d1d0a5264b48cc9edbf017c54ab27018");
	}

	@Override
	public MovieDTO getMovieDTOBySourceId(int sourceId) {
		return getMovieDTO(getTmdbMovieById(sourceId));
	}
	
	@Override
	public synchronized List<MovieDTO> findMovieDTOByName(String name) {
		List<net.sf.jtmdb.Movie> tmdbMovies = null;
		
		try {
			tmdbMovies = net.sf.jtmdb.Movie.search(name);
		} catch (IOException e) {
			e.printStackTrace();
		} catch (JSONException e) {
			e.printStackTrace();
		}
		
		if(tmdbMovies == null) // no valid api key defined in generalsettings
			throw new RuntimeException("invalid API key for TMDB model");

		List<MovieDTO> movies = new ArrayList<MovieDTO>();
		for(net.sf.jtmdb.Movie tmdbMovie : tmdbMovies)
			movies.add(getMovieDTO(tmdbMovie));
		
		return movies;
	}

	public synchronized net.sf.jtmdb.Movie getTmdbMovieById(int sourceId) {
		net.sf.jtmdb.Movie tmdbMovie = null;
		
		try {
			tmdbMovie = net.sf.jtmdb.Movie.getInfo(sourceId);
		} catch (IOException e) {
			e.printStackTrace();
		} catch (JSONException e) {
			e.printStackTrace();
		}
		
		if(tmdbMovie == null) // no valid api key defined in generalsettings
			throw new RuntimeException("invalid API key for TMDB model");
		
		return tmdbMovie;
	}
	
	/**
	 * Creates a MovieDTO object from a given
	 * jmtbmovie object (created by jmtb API)
	 * only used for presentation
	 * 
	 * @param tmdbMovie
	 * @return MovieDTO
	 */
	private MovieDTO getMovieDTO(net.sf.jtmdb.Movie tmdbMovie) {
		MovieDTO movieDto = new MovieDTO();
		
		// create a Movie object from the tmdb Movie object
		movieDto.setSourceId(tmdbMovie.getID());
		movieDto.setOriginalSourceType(OriginalSourceType.TMDB);
		movieDto.setName(tmdbMovie.getName());
		movieDto.setReleasedDate(tmdbMovie.getReleasedDate());
		movieDto.setOverview(tmdbMovie.getOverview());
		movieDto.setLanguage(tmdbMovie.getLanguage());
		movieDto.setRating(tmdbMovie.getRating());
		
		// retreive cover url
		MovieImages images = tmdbMovie.getImages();
		if(images.posters.size() > 0) {
			MoviePoster poster = (MoviePoster) images.posters.toArray()[0];
			URL coverUrl = poster.getImage(MoviePoster.Size.COVER);
			movieDto.setCoverUrl(coverUrl.toString());
				
			try {
				// write image url to a bytearray
				BufferedImage source = ImageIO.read(coverUrl);
				movieDto.setCover(source);
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
			
		return movieDto;
	}

}
